package com.epam.debrecen.hackathon.com;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.StringReader;
import java.util.LinkedList;
import java.util.List;

import org.apache.commons.io.IOUtils;

import com.epam.debrecen.hackathon.Main;
import com.epam.debrecen.hackathon.ai.model.Card;
import com.epam.debrecen.hackathon.ai.model.GameState;
import com.epam.debrecen.hackathon.ai.model.Hand;

public class InitStateResolver {

	private static final String BATTLE_END = "BattleEnd";

	private static final String BATTLE_START = "BattleStart";

	private static final String ROUND_START = "RoundStart";

	private static final String CURRENT_ZONE = "CurrentZone";

	private static final String PROTECT = "Protect";

	public ServerState resolve(String response,GameState gameState) throws IOException {

		ServerState initState = new ServerState();

		if (Main.DEBUG) {
			System.out.println("response:" + response.replaceAll("\n", " "));
		}

		BufferedReader reader = new BufferedReader(new StringReader(response));

		String line = null;

		while ((line = reader.readLine()) != null) {

			if (line.equals("Players [")) {
				gameState.setPlayers(this.readBody(reader));
			} else if (line.startsWith(InitStateResolver.ROUND_START)) {
				gameState.startRound();
			} else if (line.equals("Hand [")) {
				gameState.dealCards(this.readBody(reader));
			} else if (line.startsWith(InitStateResolver.BATTLE_START)) {
				gameState.startBattle();
			} else if (line.equals("Order [")) {
				gameState.setOrder(this.readBody(reader));
			} else if (line.startsWith(InitStateResolver.CURRENT_ZONE)) {
				gameState.setCurrentZone(line);
			} else if (line.equalsIgnoreCase("GameStart")) {
				gameState.startGame();
			} else if (line.startsWith("GameEnd")) {
				gameState.endGame();
			} else if (line.startsWith(InitStateResolver.BATTLE_END)) {
				initState.setBattleEnd(true);
				gameState.endBattle(this.processBattleEndPlayer(line));
			} else if (line.startsWith(InitStateResolver.PROTECT)) {
				gameState.protect(this.processProtected(line));
			} else if (line.startsWith("RoundEnd")) {
				gameState.endRound();
			} else if (line.startsWith("Player ")) {
				String name = line.split(" ")[1].trim();
				String readLine = reader.readLine();
				if (readLine != null && readLine.startsWith("Play ")) {
					Card card = Card.fromName(readLine.split(" ")[1].trim());
					initState.addCard(name, card);
				}
				initState.setCurrentPlayer(name);
			} else {

			}
		}

		IOUtils.closeQuietly(reader);//??

		return initState;
	}

	private String processProtected(String line) {
		String region = line.substring(InitStateResolver.PROTECT.length() + 1);
		return "(null)".equalsIgnoreCase(region) ? null : region;
	}

	private String processBattleEndPlayer(String line) {
		return line.substring(InitStateResolver.BATTLE_END.length() + 1);
	}

	private String processCurrentZone(String line) {
		return line.substring(InitStateResolver.CURRENT_ZONE.length() + 1);
	}

	private Integer processBattle(String line) {
		return Integer.valueOf(line.substring(InitStateResolver.BATTLE_START.length() + 1));
	}

	private Integer processRound(String line) {
		return Integer.valueOf(line.substring(InitStateResolver.ROUND_START.length() + 1));
	}

	private List<String> readBody(BufferedReader reader) throws IOException {
		List<String> lines = new LinkedList<String>();
		String line = null;
		while ((line = reader.readLine()) != null && !line.equals("]")) {
			lines.add(line);
		}
		return lines;
	}

	private Hand processHand(List<String> handResponse) {
		Hand hand = new Hand();

		for (String card : handResponse) {
			hand.addCard(card);
		}

		return hand;
	}

	private List<String> processOrderState(List<String> order) {
		return order;
	}

	private PlayerState processPlayerState(List<String> lines) {
		return new PlayerState(lines);
	}
}
